package com.xuanyaun.coreutils.file

import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.text.format.DateUtils
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream

/**
 * @FileName:
 * @Description:
 * @author ken.luo
 * @date 2023/4/4
 * @version V1.0
 * @email 424533553@qq.com
 */
object FileIOUtils {
    val TAG = "FileIOUtils"
    
    /**
     * 通过两个路径地址生成对应的输入输出流
     * 主要方式获取ContentResolver.openOutputStream(insertUri)
     */
    fun copyFile(context : Context,contentResolver : ContentResolver,sourceFilePath : String,insertUri : Uri) : Boolean {
        var inputStream : InputStream? = null //输入流
        var outputStream : OutputStream? = null //输出流
        return try {
            var isCopySuccess = false
            outputStream = contentResolver.openOutputStream(insertUri)?.also { outStream->
                val sourceFile = File(sourceFilePath)
                if (sourceFile.exists()) { // 文件存在时
                    // 读入原文件
                    inputStream = FileInputStream(sourceFile).also { inStream->
                        //输入流读取文件，输出流写入指定目录
                        isCopySuccess = copyFileWithStream(outStream,inStream)
                    }
                }
            }
            isCopySuccess
        } catch (e : Exception) {
            e.printStackTrace()
            false
        } finally {
            try {
                inputStream?.close()
                outputStream?.close()
            } catch (e : IOException) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 利用输入输出流边读边写，将文件(图片)写入指定路径
     */
    private fun copyFileWithStream(outputStream : OutputStream,inputStream : InputStream) : Boolean {
        var isSuccess : Boolean
        try {
            inputStream.use { ins->
                val buf = ByteArray(2048)
                var len : Int
                while (ins.read(buf).also { len = it } != -1) {
                    outputStream.write(buf,0,len)
                }
                outputStream.flush()
            }
            isSuccess = true
        } catch (e : IOException) {
            Log.e(TAG,Log.getStackTraceString(e))
            isSuccess = false
        } finally {
            try {
                outputStream.close()
                inputStream.close()
            } catch (e : IOException) {
                e.printStackTrace()
            }
        }
        return isSuccess
    }
    
    /**
     * android 10 以下版本
     */
    private fun saveImageToGallery(context : Context,image : Bitmap,saveDir : String,saveName : String) : Boolean {
        val appDir = File(saveDir)
        if (!appDir.exists()) {
            appDir.mkdir()
        }
        val fileName = "$saveName.png"
        val file = File(appDir,fileName)
        try {
            val fos = FileOutputStream(file)
            // 通过io流的方式来压缩保存图片
            val isSuccess = image.compress(Bitmap.CompressFormat.JPEG,100,fos)
            fos.flush()
            fos.close()
            //TODO  这种广播的方式已经废弃了 保存图片后发送广播通知更新数据库
            val uri = Uri.fromFile(file)
            context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri))
            return isSuccess
        } catch (e : IOException) {
            e.printStackTrace()
        }
        return false
    }
    
    /**
     * android 10 以上版本  将bitmap保存到相册中
     */
    private fun saveImageToGalleryQ(context : Context,image : Bitmap,saveDir : String,saveName : String) : Boolean {
        val mImageTime = System.currentTimeMillis()
        val mImageFileName = "$saveName.png"
        val values = ContentValues()
        values.put(MediaStore.MediaColumns.RELATIVE_PATH,saveDir)
        values.put(MediaStore.MediaColumns.DISPLAY_NAME,mImageFileName)
        values.put(MediaStore.MediaColumns.MIME_TYPE,"image/png")
        values.put(MediaStore.MediaColumns.DATE_ADDED,mImageTime / 1000)
        values.put(MediaStore.MediaColumns.DATE_MODIFIED,mImageTime / 1000)
        values.put(MediaStore.MediaColumns.DATE_EXPIRES,(mImageTime + DateUtils.DAY_IN_MILLIS) / 1000)
        values.put(MediaStore.MediaColumns.IS_PENDING,1)
        val resolver = context.contentResolver
        val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values)
        try {
            val out = resolver.openOutputStream(uri!!)
            if (!image.compress(Bitmap.CompressFormat.PNG,100,out!!)) {
                return false
            }
            values.clear()
            values.put(MediaStore.MediaColumns.IS_PENDING,0)
            values.putNull(MediaStore.MediaColumns.DATE_EXPIRES)
            resolver.update(uri,values,null,null)
        } catch (e : java.lang.Exception) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                resolver.delete(uri!!,null)
            }
            return false
        }
        return true
    }
    
    /**
     * android 10及以上版本通过ContentResolver删除指定的目录
     */
    private fun deleteImages(context : Context,saveDir : String) {
        var relativePath = saveDir
        //判断是否有加斜杠
        if (!relativePath.endsWith("/")) {
            relativePath += File.separator
        }
        val projection = arrayOf(MediaStore.Images.Media._ID,MediaStore.Images.Media.RELATIVE_PATH)
        val selection = "${MediaStore.Images.Media.RELATIVE_PATH}=?"
        val selectionArgs = arrayOf(relativePath)
        context.contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection,arrayOf(relativePath))
    }
    
    
}